// 01-14-2007 Time: 1:46pm
/*
 * NetworkServer.java
 *
 * Created on December 15, 2006, 10:29 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package gamefiles;

import java.net.*;
import java.io.*;

/**
 *
 * @author SergeevI
 */
public class NetworkServer
{
    public static final int ERROR = -1;
    public static final int ERROR_OK = 0;
    public static final int ERROR_IO_EXCEPTION = -2;
    public static final int ERROR_SERVER_NOT_INITIALIZED = -3;
    public static final int ERROR_CLIENT_NOT_INITIALIZED = -4;
    public static final int ERROR_CLIENT_ALREADY_ACCEPTED = -5;
    public static final int ERROR_READ_TIMEOUT = -6;
    
    private ServerSocket ssock;
    private Socket csock;
    private int sPort;
    private int sTimeout;
    private String strExceptionError;
    private BufferedReader inClient;
    private PrintStream outClient;
    
    public int errCode;
    
    public NetworkServer (int port)
    {
        // Clear sockets
        csock = null;
        ssock = null;
        
        // Reset errors
        errCode = ERROR_OK;
        strExceptionError = "";
        
        // Set server port
        sPort = port;
        
        // Set socket timeout to 0 (blocking)
        sTimeout = 0;
    }
    
    public NetworkServer (int port, int timeout)
    {
        // Clear sockets
        csock = null;
        ssock = null;
        
        // Reset errors
        errCode = ERROR_OK;
        strExceptionError = "";
        
        // Set server port
        sPort = port;
        
        // Set socket timeout
        sTimeout = timeout;
    }
    
    public String errorToString() {
        switch (errCode) {
            case ERROR_IO_EXCEPTION:
                return "IO Exception: " + strExceptionError;
            case ERROR_SERVER_NOT_INITIALIZED:
                return "Server socket has not been initialized!";
            case ERROR_CLIENT_NOT_INITIALIZED:
                return "Client socket has not been initialized!";
            case ERROR_CLIENT_ALREADY_ACCEPTED:
                return "Client socket has already been accepted!";
            
            case ERROR_OK:    
            default:
                return "No error.";
        }
    }
    
    public int init() {
        errCode = ERROR_OK;
        
        try {
            ssock = new ServerSocket(sPort);
        } catch (IOException e) {
            strExceptionError = "Error creating server socket!: " + e.toString();
            errCode = ERROR_IO_EXCEPTION;
        }
        return errCode;
    }
    
    public int acceptClient() {
        errCode = ERROR_OK;
        
        if (ssock == null) {
            errCode = ERROR_SERVER_NOT_INITIALIZED;
            return errCode;
        }
        
        try {
            csock = ssock.accept();
			inClient = new BufferedReader(
						new InputStreamReader(
							csock.getInputStream()));
			outClient = new PrintStream(csock.getOutputStream ());
                csock.setSoTimeout(sTimeout);
        } catch (IOException e) {
            strExceptionError = "Error accepting client!: " + e.toString();
            errCode = ERROR_IO_EXCEPTION;
        }
        return errCode;
    }
    
    public int disconnectClient() {
        errCode = ERROR_OK;
        if (csock == null)
            return errCode;
        
        try {
            csock.close();
            csock = null;
        } catch (IOException e) {
            strExceptionError = "Error closing client!: " + e.toString();
            errCode = ERROR_IO_EXCEPTION;
        }
        return errCode;
    }
    
    public int close() {
        errCode = ERROR_OK;
        if (ssock == null)
            return errCode;
        
        try {
            ssock.close ();
            ssock = null;
        } catch (IOException e) {
            strExceptionError = "Error closing server!: " + e.toString();
            errCode = ERROR_IO_EXCEPTION;
        }
        return errCode;
    }
    
    public String readLine() {
        errCode = ERROR_OK;
        
        if (assertSockets() == -1)
            return null;
        
        try {
            return inClient.readLine();
        } catch (SocketTimeoutException e) {
                errCode = ERROR_READ_TIMEOUT;
                return null;
        } catch (IOException e) {
            errCode = ERROR_IO_EXCEPTION;
            strExceptionError = "Error reading from client!: " + e.toString ();
            return null;
        }
    }
    
    public int writeLine(String data) {
        errCode = ERROR_OK;
        
        if (assertSockets() < ERROR_OK)
            return errCode;
        
        outClient.println(data);
        return errCode;
    }
    
    public int assertSockets() {
        errCode = ERROR_OK;
        if (ssock == null) {
            errCode = ERROR_SERVER_NOT_INITIALIZED;
            return errCode;
        }
        
        if (csock == null) {
            errCode = ERROR_CLIENT_NOT_INITIALIZED;
            return errCode;
        }
        
        return errCode;
    }
    
    public boolean isConnected() {
        if (assertSockets() < ERROR_OK)
                return false;
        return csock.isConnected();
    }
}
